﻿using System;
using System.Collections.Generic;

namespace Hsenl {
    [FrameworkMember]
    public static class PriorityModify {
        private static readonly Dictionary<string, Modifier> _modifiers = new();

        [OnEventSystemInitialized]
        private static void Cache() {
            Unload();
        }

        [OnEventSystemUnload]
        private static void Unload() {
            _modifiers.Clear();
        }

        public static void Modify<T>(string type, string key, T target, int priority, Action<T> action) {
            if (!_modifiers.TryGetValue(type, out var result)) {
                result = ObjectPool.Rent<Modifier<T>>();
                _modifiers[type] = result;
            }

            var modifier = (Modifier<T>)result;
            modifier.target = target;
            var position = 0;
            var contains = false;
            for (int i = 0, len = modifier.modifyActions.Count; i < len; i++) {
                var tuple = modifier.modifyActions[i];
                if (tuple.key == key) {
                    position = i;
                    contains = true;
                    break;
                }

                if (priority < tuple.priority) {
                    position = i;
                }

                if (i == len - 1) {
                    position = i + 1;
                }
            }

            if (!contains)
                modifier.modifyActions.Insert(position, (key, priority, action));

            if (position == 0) {
                action.Invoke(modifier.target);
            }
        }

        public static void UnregisterModify<T>(string type, string key, Action<T> action) {
            if (!_modifiers.TryGetValue(type, out var result)) {
                return;
            }
            
            var modifier = (Modifier<T>)result;
            var position = 0;
            var contains = false;
            for (int i = 0, len = modifier.modifyActions.Count; i < len; i++) {
                var tuple = modifier.modifyActions[i];
                if (tuple.key == key) {
                    position = i;
                    contains = true;
                    modifier.modifyActions.RemoveAt(i);
                    break;
                }
            }

            if (contains) { // 如果成功移除了, 且移除的是排名第一的修改, 则执行注销修改, 然后, 顺位让之前的第二位执行修改
                if (position == 0) {
                    action.Invoke(modifier.target);
                    if (modifier.modifyActions.Count != 0) {
                        var tuple = modifier.modifyActions[0];
                        tuple.action.Invoke(modifier.target);
                    }
                }
            }
        }

        public class Modifier { }

        public class Modifier<T> : Modifier {
            public T target;
            public readonly List<(string key, int priority, Action<T> action)> modifyActions = new();
        }
    }
}